package me.jiatao.javestudy.generic.wildcard_type;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;

/**
 * Created by JiaTao on 2018/9/12.
 * Email: 535318720@qq.com
 * Version: 1.0
 * Description:
 */
public class PointWildcardMain {
    public static void main(String[] args) {
        Class<?> clazz = PointWildcardImpl.class;
        //此时的type对应PointSingleInterface<Comparable<? extends Number>>
        Type[] types = clazz.getGenericInterfaces();
        for (Type type : types) {
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                //得到填充PointSingleInterface的具体参数，即：Comparable<? extends Number>，仍然是一个ParameterizedType
                Type[] actualTypes = parameterizedType.getActualTypeArguments();
                for (Type actualType : actualTypes) {
                    if (actualType instanceof ParameterizedType) {
                        ParameterizedType ComparableType = (ParameterizedType) actualType;
                        //对Comparable<? extends Number>再取填充参数，得到的type对应<? extends Number>，这个就是WildcardType了
                        Type[] compareArgs = ComparableType.getActualTypeArguments();
                        for (Type Arg : compareArgs) {
                            if (Arg instanceof WildcardType) {
                                //将得到的对应WildcardType的type强转为WildcardType的变量
                                WildcardType wt = (WildcardType) Arg;

                                //利用getLowerBounds得到下界，即派生自Super的限定，如果没有派生自super则为null
                                Type[] lowerBounds = wt.getLowerBounds();
                                for (Type bound : lowerBounds) {
                                    Class<?> boundClass = (Class) bound;
                                    System.out.println("lowerBound为：" + boundClass.getName());
                                }

                                //通过getUpperBounds得到上界，即派生自extends的限定，如果没有，默认是Object
                                Type[] upperBounds = wt.getUpperBounds();
                                for (Type bound : upperBounds) {
                                    Class<?> boundClass = (Class) bound;
                                    //如果不写，则默认输出Object，如果写了，则输出对应的
                                    System.out.println("upperBound为：" + boundClass.getName());
                                }

                            }
                        }
                    }
                }

            }
        }
    }
}
